﻿namespace ScrumLite.WebUx.JsonProxy
{
    using System;
    using System.Collections.ObjectModel;
    using System.Linq;
    using System.Net;
    using System.ServiceModel;
    using System.ServiceModel.Web;
    using ScrumLite.Services;
    using ScrumLite.Services.Contracts;
    using System.Globalization;

    [ServiceContract(Namespace = "")]
    public class Requests
    {
        IRequestsService requests;

        const int requestperpage = 20;

        public Requests()
            : this(new LinqRequestsService())
        {
        }

        public Requests(IRequestsService requests)
        {
            this.requests = requests;
        }

        [OperationContract]
        [WebGet(UriTemplate = "ReadCommitted?project={projectId}", ResponseFormat = WebMessageFormat.Json)]  
        public Request[] GetCommitted(string projectId)
        {
            Request[] data = this.requests.GetCommittedRequests(projectId);
            Requests.SetCaching(WebOperationContext.Current, DateTime.Now, 10); // 10 seconds
            return data;
        }

        [OperationContract]
        [WebGet(UriTemplate = "ReadAll?project={projectId}&workArea={workArea}", ResponseFormat = WebMessageFormat.Json)]
        public Request[] GetAll(string projectId, string workArea)
        {
            Collection<Request> data = this.requests.GetRequests(projectId, workArea);
            Requests.SetCaching(WebOperationContext.Current, DateTime.Now, 10); // 10 seconds
            return data.ToArray();
        }

        [OperationContract]
        [WebGet(UriTemplate = "ReadPage?project={projectId}&workArea={workArea}&nPage={pageNumber}", ResponseFormat = WebMessageFormat.Json)]
        public RequestPage GetPage(string projectId, string workArea, int pageNumber)
        {
            Collection<Request> data = this.requests.GetRequests(projectId, workArea);

            int npages = data.Count / requestperpage;

            if (data.Count % requestperpage != 0)
                npages++;

            if (pageNumber < 0)
                pageNumber = npages - 1;

            Requests.SetCaching(WebOperationContext.Current, DateTime.Now, 10); // 10 seconds

            Collection<Request> result = new Collection<Request>();

            for (int k=pageNumber*requestperpage; k< data.Count && k <(pageNumber+1)*requestperpage; k++)
                result.Add(data[k]);

            RequestPage page = new RequestPage();
            page.NoPage = pageNumber;
            page.NoPages = npages;
            page.Requests = result.ToArray();
            return page;
        }

        [OperationContract]
        [WebGet(UriTemplate = "GetNoPage?project={projectId}&workArea={workArea}", ResponseFormat = WebMessageFormat.Json)]
        public int GetNoPage(string projectId, string workArea)
        {
            Collection<Request> data = this.requests.GetRequests(projectId, workArea);

            int npages = data.Count / requestperpage;

            if (data.Count % requestperpage != 0)
                npages++;

            return npages;
        }

        [OperationContract]
        [WebGet(UriTemplate = "ReadOpened?project={projectId}", ResponseFormat = WebMessageFormat.Json)]
        public Request[] GetOpened(string projectId)
        {
            Request[] data = this.requests.GetOpenedRequests(projectId);
            Requests.SetCaching(WebOperationContext.Current, DateTime.Now, 10); // 10 seconds
            return data;
        }

        [OperationContract]
        [WebInvoke(UriTemplate = "WriteCommitted?project={projectId}", RequestFormat=WebMessageFormat.Json)]
        public void WriteCommitted(string projectId, Request[] data)
        {
            this.requests.SaveRequests(projectId, data);
        }

        [OperationContract]
        [WebInvoke(UriTemplate = "Delete?id={id}", RequestFormat = WebMessageFormat.Json)]
        public void DeleteRequest(Guid id)
        {
            this.requests.DeleteRequest(id);
        }

        private static void SetCaching(WebOperationContext context, DateTime lastModifiedDate, Int32 maxCacheAge)
        {
            // set CacheControl header
            HttpResponseHeader cacheHeader = HttpResponseHeader.CacheControl;
            String cacheControlValue = String.Format(CultureInfo.InvariantCulture, "max-age={0}, must-revalidate", maxCacheAge);
            context.OutgoingResponse.Headers.Add(cacheHeader, cacheControlValue);

            // set cache validation 
            context.OutgoingResponse.LastModified = lastModifiedDate;
            String tag = context.IncomingRequest.UriTemplateMatch.RequestUri.ToString() + lastModifiedDate.ToString();
            context.OutgoingResponse.ETag = tag;
        }
    }
}
